package com.yanqu.road.server;

import com.yanqu.road.NettyMgr;
import com.yanqu.road.dao.db.DBTableInfoMgr;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.server.agent.AgentInterfaceMgr;
import com.yanqu.road.server.channelserver.manager.activity.entername.ChannelEnterNameMgr;
import com.yanqu.road.server.channelserver.manager.activity.entername.ChannelEnterNameRankMgr;
import com.yanqu.road.server.channelserver.manager.activity.luckydraw.ChannelLuckyDrawMgr;
import com.yanqu.road.server.channelserver.manager.activity.pasture.ChannelPastureMgr;
import com.yanqu.road.server.channelserver.manager.activity.tonbing.ChannelTonBingMgr;
import com.yanqu.road.server.channelserver.manager.activity.washe.ChannelWasheMgr;
import com.yanqu.road.server.channelserver.manager.activity.washepk.ChannelWashePkMgr;
import com.yanqu.road.server.channelserver.manager.server.ChannelXServerNameMgr;
import com.yanqu.road.server.channelserver.manager.user.ChannelUserMgr;
import com.yanqu.road.server.channelserver.manager.voucher.ChannelVoucherMgr;
import com.yanqu.road.server.channelserver.manager.xrank.ChannelXRankMgr;
import com.yanqu.road.server.channelserver.timer.ChannelServerTimerMgr;

import java.util.ArrayList;
import java.util.List;

public class ChannelServer extends ChannelBaseServer {

    private static ChannelServer channelServer;

    public static ChannelServer getInstance() {
        if (null == channelServer) {
            channelServer = new ChannelServer();
            if(null == ChannelBaseServer.channelBaseServer) {
                ChannelBaseServer.channelBaseServer = channelServer;
            }else {
                logger.error("ChannelServer getInstance baseServer exist");
            }
        }
        return channelServer;
    }

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        if (args.length <= 0) {
            System.err.println("check set config path");
            return;
        }

        cfgPath = args[0];

        ChannelServer channelServer = ChannelServer.getInstance();
        channelServer.setServerType(Integer.valueOf(args[1]));
        if (!channelServer.start(channelServer.getServerType(), ChannelServer.class.getName())) {
            System.err.println("ChannelServer start fail!");
            System.exit(1);
            return;
        }

        //扫描日志库
        DBTableInfoMgr dbTableInfoMgr = new DBTableInfoMgr();
        dbTableInfoMgr.init(DbNameStrategy.getChannelServerDb(), "com.yanqu.road.entity.log", true);
        channelServer.setDbTableInfoMgr(dbTableInfoMgr);

        //初始化定时器
        ChannelServerTimerMgr.initGeneralTimers(channelServer.getServerType());
        System.err.println("ChannelServer start success");
        logger.info("ChannelServer start success,cost time:" + (System.currentTimeMillis() - time));
        TempServer.tempServerLogger.info("notify process start success!");

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            logger.info("ChannelServer 关闭服务器");
            ChannelServer.getInstance().newStop();
        }, "ShutdownHook"));
    }

    public boolean newStop() {
        try {
            logger.info("stop server begin...");

            // 关闭netty端口
            logger.info("stop netty ing...");
            NettyMgr.newStop();

            // 停止定时器
            logger.info("stop timer ing...");
            ChannelServerTimerMgr.newStop();

            // 保存mgr数据
            logger.info("save mgr data ing...");
            for (TempMgr tempMgr : ChannelServer.getInstance().getMgrList()) {
                try {
                    tempMgr.save();
                }catch (Exception e){
                    logger.error("mgr save error:", e);
                }
            }

            // 停mgr
            logger.info("call mgr stop ing...");
            for (TempMgr baseMgr : ChannelServer.getInstance().getMgrList()) {
                baseMgr.stop();
            }

            TempServer.deleteFile("./crossServer.pid");
            super.stopWithLogger();
            System.out.println("ChannelServer 服务器已关闭");
            /* todo 后面再改
            // 关log4j日志
            org.apache.logging.log4j.LogManager.shutdown();
            logger.error("shutdown LogManager finish");
             */
        } catch (Exception e) {
            logger.error("ChannelServer stop error", e);
            return false;
        }
        return true;
    }

    @Override
    public boolean stop() {
        try {
            super.stop();
            //保存mgr数据
            for (TempMgr tempMgr : getInstance().getMgrList()) {
                try {
                    tempMgr.save();
                }catch (Exception e){
                    logger.error("mgr save error:", e);
                }
            }
        } catch (Exception e) {
            logger.error("ChannelServer close error", e);
            return false;
        }
        return true;
    }

    @Override
    public List<TempMgr> getMgrList() {
        List<TempMgr> mgrList = new ArrayList<>();
        //配置放前面
        mgrList.add(new AgentInterfaceMgr());
        //活动mgr
        mgrList.add(new ChannelXRankMgr());
        mgrList.add(new ChannelXServerNameMgr());
        mgrList.add(new ChannelWasheMgr());
        mgrList.add(new ChannelLuckyDrawMgr());
        mgrList.add(new ChannelPastureMgr());
        mgrList.add(new ChannelWashePkMgr());
        mgrList.add(new ChannelUserMgr());
        mgrList.add(new ChannelTonBingMgr());

        // 代金券模块
        mgrList.add(new ChannelVoucherMgr());

        //放后面
        mgrList.add(new ChannelEnterNameMgr());
        mgrList.add(new ChannelEnterNameRankMgr());
        return mgrList;
    }

}
